
<svelte:window on:resize="measure()" />

<div 
  ref:root
  class="root" 
  on:pointerdown="down(event)"
  style="cursor: {cursor}; position: absolute;"
>
  {#if extent}
  <svg width={clientWidth} height={clientHeight}>
    {#if left && right && top && bottom}
      <path
        class="{background ? '' : 'transparent'}"
        d="M0,0 L{clientWidth},0 L{clientWidth},{clientHeight} L0,{clientHeight} z M{left},{top} L{left},{bottom} L{right},{bottom} L{right},{top} z"
      />
    {/if}
  </svg>
  <div
    class="reticle {round ? 'round' : ''}"
    style="
      border-color: {color};
      top:{top - 1}px;
      left:{left - 1}px; 
      width:{right - left + 2}px; 
      height:{bottom - top + 2}px; 
      "
  >
    {#if annotationValue}
      <div class="annotationTabParent" style="top:{(w * width-2)/2}px;">
        <div class="annotationTab" style="background:{color};">
          <div class="annotation">{annotationValue}</div>
        </div>
      </div>
    {/if}
  </div>
  {/if}
</div>

<script>
  export default {
    data() {
      return {
        dragging: false,
        extent: [[0, 0],[0, 0]],
        background: true,
        round: false,
        color: "rgb(255, 130, 0)",
        enableDragging: true,
        upListener: null,
        moveListener: null,
        cursor: 'grab',
        clientWidth: 98,
        clientHeight: 98
      }
    },
    computed: {
      left: ({clientWidth, extent}) => Math.min(clientWidth, Math.max(1e-6, extent[0][0] * clientWidth)),
      right: ({clientWidth, extent}) => Math.min(clientWidth, extent[0][1] * clientWidth),
      top: ({clientHeight, extent}) => Math.min(clientHeight, Math.max(1e-6, extent[1][0] * clientHeight)),
      bottom: ({clientHeight, extent}) => Math.min(clientHeight, extent[1][1] * clientHeight),
    },
    oncreate() {
      setTimeout(() => this.measure(), 10);
    },
    methods: {
      measure() {
        this.set({
          clientWidth: this.refs.root.offsetWidth,
          clientHeight: this.refs.root.offsetHeight,
        })
      },
      up() {
        const {upListener, moveListener} = this.get();
        window.removeEventListener("pointermove", moveListener);
        window.removeEventListener("pointerup", upListener);
        this.set({cursor: "grab"});
      },
      down(event) {
        event.preventDefault();
        const {enableDragging, clientWidth, clientHeight} = this.get();
        if (enableDragging) {
          this.move(event);
        }
        const upListener = this.up.bind(this);
        window.addEventListener("pointerup", upListener);
        const moveListener = this.move.bind(this);
        window.addEventListener("pointermove", moveListener);
        this.set({upListener, moveListener, cursor: "grabbing"});
      },
      move(event) {
        const {clientWidth, clientHeight} = this.get();
        const gcx = event.offsetX / clientWidth; 
        const gcy = event.offsetY / clientHeight;
        this.set({
          gcx,
          gcy,
          startPos: {x: event.screenX, y: event.screenY},
        });
        this.fire("drag", {gcx, gcy});
      },
    },
  }
</script>

<style>
  svg {
    position: absolute;
    top: 0;
    left: 0;
  }
  svg path {
    fill: white;
    fill-opacity: 0.7;
  }
  svg path.transparent {
    fill-opacity: 0;
  }
  .root {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
  }
  .reticle {
    top: 0;
    left: 0;
    position: absolute;
    border: solid 1px black;
    border-width: 2px;
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    background: rgba(0, 0, 0, 0);
    border-radius: 4px;
    pointer-events: none;
  }
  .reticle.round {
    border-radius: 50%;
  }
  .annotationTabParent {
    position: absolute;
    left:0px;
  }
  .annotationTab {
    width: 16px;
    height: 16px;
    left: -16px;
    top: -8px;
    position: absolute;
    border-radius: 3px 0px 0px 3px;
  }
  p.annotation {
    font-size: 12px;
    top: 0px;
    left: 4px;
    color: white;
    position: absolute;
    text-align: center;
    line-height: 1em;
  }
</style>
